package nets

import (
	"context"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	"github.com/wutianze/nats.go"
	"time"
)

type NetContext struct {
	Data *nats.Msg
}

type Net struct {
	ctx   context.Context
	label string

	url string
	nc  *nats.Conn
}

func (r *Net) InitFlag(flags *pflag.FlagSet) {
	flags.String(r.label+".url", "nats://39.101.140.145:4222", "")
}

func (r *Net) InitViper(viper *viper.Viper) {
	r.url = viper.GetString(r.label + ".url")

	//r.url = viper.GetString("NATS_URL")
}

func (r *Net) Connect() error {
	nc, err := nats.IConnect(r.url)
	if err != nil {
		return err
	}
	r.nc = nc
	return nil
}

func (r *Net) Subscribe(subject string, f func(m NetContext)) (*nats.Subscription, error) {
	c, err := r.nc.ISubscribe(subject, func(msg *nats.Msg) {
		f(NetContext{Data: msg})
	})
	if err != nil {
		return nil, err
	}
	return c, nil
}

func (r *Net) Request(subject string, req []byte) ([]byte, error) {
	d, err := r.nc.IRequest(subject, req, 10*time.Second)
	if err != nil {
		return nil, err
	}
	return d, nil
}

func (r *Net) Publish(subject string, req []byte) error {
	return r.nc.IPublish(subject, req)
}

func (r Net) Close() error {
	r.nc.Close()
	return nil
}

func NewNets(ctx context.Context, label string) GlueNets {
	return &Net{
		ctx:   ctx,
		label: label,
	}
}
